/**
 *
 * Module        : Module Size
 * Authors       : Ben Kwint & Arie van der Veek
 * Date          : November 7th 2011
 * Description   : MainMetrics entry point to the application, handles the 
 *                 bulk of the work
 *
 *                 All metrics are calculated including test classes
 *				   Testclasses are also part of the code that needs
 *				   to be maintained, so it also needs to be maintainable
 *				   Expection to this rule is test coverage, as testclasses
 *				   are not tested themselves.
 *
 */
module MainMetrics

import lang::java::jdt::Java;
import lang::java::jdt::JDT;
import Graph;
import IO;
import Benchmark;
import Time;

import Constants;
import InOut::Output;
import Metrics::CC;
import Metrics::Duplication;
import Metrics::Loc;
import Metrics::ModuleSize;
import Metrics::TestCoverage;
import Metrics::UnitSize;


public void main(){
  println("Start calculate metrics");
  
  // First calculate the lines of code
  int startTime = getMilliTime();
  int LOC = countLOCForProject(Constants::FILEPROJLOC);
  int doneLoc = getMilliTime();
  if ( Constants::SHOWTIME) println("Time spent on Lines of Code <(doneLoc - startTime)/1000> seconds");
  
  // Parse the eclipse project, this will be used for later metric calculation
  parsedProject = extractProject(Constants::ECLIPSEPROJLOC);
  int doneParsing= getMilliTime();
  if ( Constants::SHOWTIME) println("Time spent on Parsing Tree <(doneParsing - doneLoc)/1000> seconds");
  
  // Calculate the LOC per Mehtod
  list[tuple[str,int]] UnitSize = countLOCPerMethod(parsedProject@methodDecls);
  int doneUnitSize= getMilliTime();
  if ( Constants::SHOWTIME) println("Time spent on calculating Unit Size <(doneUnitSize - doneParsing)/1000> seconds");
  
  //Calculate the Cyclomatic Complexity.
  list[tuple[str,int]] CycloComp = calculateCyclometricComplexity(parsedProject@methodBodies, 0);
  int doneCC= getMilliTime();
  if ( Constants::SHOWTIME) println("Time spent on calculating Cyclomatic Complexity <(doneCC - doneUnitSize)/1000> seconds");
  
  // Caclucalate the code duplication.
  int DuplicatedCode = calculateDuplication(parsedProject@methodDecls, 6);
  int doneDup= getMilliTime();
  if ( Constants::SHOWTIME) println("Time spent on calculating duplication <(doneDup - doneCC)/1000> seconds");

  // If the testcoverage option is enabled, calculate the testcoverage and generate report with
  // test coverage. Otherwise only generate report without test coverage.
  real testCoverage = 0.0;
  if (Constants::CALCTESTCOV) testCoverage = calculateTotalTestCoverage(Constants::FILEPROJLOC); 
  if (Constants::CALCTESTCOV) GenerateReport(LOC, UnitSize, CycloComp, DuplicatedCode,testCoverage); else GenerateReport(LOC, UnitSize, CycloComp, DuplicatedCode);
  println("End calculate metrics");
  int totalTime = (getMilliTime() - startTime)/1000;
  if ( totalTime<60) println("Time spent on calculating metrics: <totalTime> seconds" ); else println("Time spent on calculating metrics: <totalTime/60> minutes and <totalTime % 60> seconds");
}
